<script module lang="ts">
    import { defineMeta } from "@storybook/addon-svelte-csf";
    import Icon from "@iconify/svelte";
    import Tree, { TreeCheckMod } from "./Tree.svelte";
    import { Link, Paragraph } from "../Typography";
    import Space from "../Space/Space.svelte";
    import img from "/src/assets/logo.svg";
    import Button from "../Button/Button.svelte";
    import { DropdownItem, DropdownMenu } from "../Dropdown";
    import type { TreeNode } from "./Tree";
    import { Input } from "../Input";
    import genData from "../../utils/utils";

    const { Story } = defineMeta({
        title: "Components/Views/Tree",
        component: Tree,
        tags: ["autodocs"],
        argTypes: {},
        args: {},
    });

    export const createArray = (count: number) => {
        return new Array(count).fill(true).map((_, index: number) => {
            return {
                id: index,
                value: 1 + Math.round(Math.random() * 20),
                text: `Row ${index}`,
            };
        });
    };

    const data1 = createArray(10000);
    const data = [
        {
            id: "beijing",
            title: "北京",
            children: [
                { id: "gugong", title: "故宫" },
                { id: "tiantan", title: "天坛" },
            ],
        },
        {
            id: "zhejiang",
            title: "浙江",
            children: [
                { id: "xihu", title: "西湖" },
                { id: "linyin", title: "灵隐" },
            ],
        },
    ];
    let expandedKeys = $state<string[]>([]);
    let selectedKey = $state("");
    let value = $state([]);

    const data2: TreeNode[] = [];
    for (let i = 0; i < 1 + Math.random() * 5; i++) {
        data2.push({ title: `node_${i}`, id: `${i}`, loading: true });
    }

    let data3: TreeNode[] = $state([]);
    for (let i = 0; i < 1 + Math.random() * 5; i++) {
        data3.push({ title: `node_${i}`, id: `${i}`, loading: true });
    }

    let searchKey = $state("");
    let searchTree: any;
    let expandTree: any;
    let interfaceTree: any;
    let appendTree: any;
    let renameTree: any;
    let bigTree: any;
</script>

<Story name="Default">
    {#snippet template(args)}
        {@const data = [
            {
                id: "beijing",
                title: "北京",
                children: [
                    { id: "gugong", title: "故宫" },
                    { id: "tiantan", title: "天坛" },
                ],
            },
            {
                id: "zhejiang",
                title: "浙江",
                children: [
                    { id: "xihu", title: "西湖" },
                    { id: "linyin", title: "灵隐" },
                ],
            },
        ]}
        <Tree {data} />
    {/snippet}
</Story>

<Story name="Expand">
    {#snippet template(args)}
        <Tree {data} bind:expandedKeys bind:this={expandTree} />

        <Button
            onclick={() => {
                if (expandedKeys.includes("beijing")) {
                    expandedKeys = [];
                } else {
                    expandedKeys.push("beijing");
                }
            }}>展开/收起</Button
        >

        <Button
            onclick={() => {
                expandTree.expandAll();
            }}>全部展开</Button
        >
        <Button
            onclick={() => {
                expandTree.collapseAll();
            }}>全部收起</Button
        >
    {/snippet}
</Story>

<Story name="Selected">
    {#snippet template(args)}
        <Tree {data} bind:selectedKey />

        <Button
            onclick={() => {
                selectedKey = "beijing";
            }}>选择节点</Button
        >
    {/snippet}
</Story>

<Story name="Draggable">
    {#snippet template(args)}
        {@const data = [
            {
                id: "beijing",
                title: "北京",
                children: [
                    { id: "gugong", title: "故宫" },
                    { id: "tiantan", title: "天坛" },
                ],
            },
            {
                id: "zhejiang",
                title: "浙江",
                children: [
                    { id: "xihu", title: "西湖" },
                    { id: "linyin", title: "灵隐" },
                ],
            },
        ]}
        <Tree {data} draggable />
    {/snippet}
</Story>

<Story name="Checkable">
    {#snippet template(args)}
        {@const data = [
            {
                id: "beijing",
                title: "北京",
                children: [
                    { id: "gugong", title: "故宫" },
                    { id: "tiantan", title: "天坛" },
                ],
            },
            {
                id: "zhejiang",
                title: "浙江",
                children: [
                    { id: "xihu", title: "西湖" },
                    { id: "linyin", title: "灵隐" },
                ],
            },
        ]}
        <Tree {data} checkable bind:value />
    {/snippet}
</Story>

<Story name="Relation">
    {#snippet template(args)}
        {@const data = [
            {
                id: "beijing",
                title: "北京",
                children: [
                    { id: "gugong", title: "故宫" },
                    { id: "tiantan", title: "天坛" },
                ],
            },
            {
                id: "zhejiang",
                title: "浙江",
                children: [
                    { id: "xihu", title: "西湖" },
                    { id: "linyin", title: "灵隐" },
                ],
            },
        ]}
        <Tree {data} checkable checkRelation="unRelated" />
    {/snippet}
</Story>

<Story name="DefaultDisabled">
    {#snippet template(args)}
        {@const data = [
            {
                id: "beijing",
                title: "北京",
                children: [
                    { id: "gugong", title: "故宫", disabled: true },
                    { id: "tiantan", title: "天坛" },
                ],
            },
            {
                id: "zhejiang",
                title: "浙江",
                children: [
                    { id: "xihu", title: "西湖" },
                    { id: "linyin", title: "灵隐" },
                ],
            },
        ]}
        <Tree {data} checkable />
    {/snippet}
</Story>

<Story name="Directory">
    {#snippet template(args)}
        {@const data = [
            {
                id: "beijing",
                title: "北京",
                children: [
                    { id: "gugong", title: "故宫" },
                    { id: "tiantan", title: "天坛" },
                ],
            },
            {
                id: "zhejiang",
                title: "浙江",
                children: [
                    { id: "xihu", title: "西湖" },
                    { id: "linyin", title: "灵隐" },
                ],
            },
        ]}
        <Tree {data} checkable directory />
    {/snippet}
</Story>

<Story name="ContextMenu">
    {#snippet template(args)}
        {#snippet contextMenu()}
            <DropdownMenu>
                <DropdownItem name="add">添加</DropdownItem>
                <DropdownItem name="modity">修改</DropdownItem>
            </DropdownMenu>
        {/snippet}
        {@const data = [
            {
                id: "beijing",
                title: "北京",
                children: [
                    { id: "gugong", title: "故宫" },
                    { id: "tiantan", title: "天坛" },
                ],
            },
            {
                id: "zhejiang",
                title: "浙江",
                children: [
                    { id: "xihu", title: "西湖" },
                    { id: "linyin", title: "灵隐" },
                ],
            },
        ]}
        <Tree
            {data}
            checkable
            directory
            oncontextmenu={(data: any) => {
                console.log(data);
            }}
            onselectmenu={(name: string) => {
                console.log(name);
            }}
            {contextMenu}
        />
    {/snippet}
</Story>
<Story name="LoadData">
    {#snippet template(args)}
        <Tree
            data={data2}
            checkable
            directory
            loadData={(data: any) => {
                return new Promise((resolve) => {
                    const d: any = [];
                    for (let i = 0; i < 1 + Math.random() * 5; i++) {
                        d.push({ title: `node_${data.id}_${i}`, id: `${data.id}_${i}` });
                    }
                    setTimeout(() => {
                        resolve(d);
                    }, 1000);
                });
            }}
        />
    {/snippet}
</Story>

<Story name="Data">
    {#snippet template(args)}
        <Tree data={data3} checkable directory />
        <Button
            type="primary"
            onclick={() => {
                const da = [];
                for (let i = 0; i < 1 + Math.random() * 5; i++) {
                    const c = [];
                    for (let j = 0; j < 1 + Math.random() * 5; j++) {
                        c.push({ title: `node_${i}_${j}`, id: `${i}_${j}` });
                    }
                    da.push({ title: `node_${i}`, id: `${i}`, children: c });
                }
                data3 = da;
            }}>改变数据</Button
        >
    {/snippet}
</Story>

{#snippet beijing()}
    <Icon icon="f7:cube-box" />
{/snippet}
<Story name="DataIcon">
    {#snippet template(args)}
        {@const data = [
            {
                id: "beijing",
                title: "北京",
                icon: beijing,
                children: [
                    { id: "gugong", title: "故宫" },
                    { id: "tiantan", title: "天坛" },
                ],
            },
            {
                id: "zhejiang",
                title: "浙江",
                children: [
                    { id: "xihu", title: "西湖" },
                    { id: "linyin", title: "灵隐" },
                ],
            },
        ]}
        <Tree {data} checkable directory />
    {/snippet}
</Story>
<Story name="CustomIcon">
    {#snippet template(args)}
        {#snippet customIcon(item: any)}
            {#if item.children}
                <Icon icon="f7:folder-fill" />
            {:else}
                <Icon icon="f7:doc-text-fill" />
            {/if}
        {/snippet}
        {@const data = [
            {
                id: "beijing",
                title: "北京",
                children: [
                    { id: "gugong", title: "故宫" },
                    { id: "tiantan", title: "天坛" },
                ],
            },
            {
                id: "zhejiang",
                title: "浙江",
                children: [
                    { id: "xihu", title: "西湖" },
                    { id: "linyin", title: "灵隐" },
                ],
            },
        ]}
        <Tree {data} checkable directory {customIcon} />
    {/snippet}
</Story>

<Story name="CustomArrow">
    {#snippet template(args)}
        {#snippet arrowIcon()}
            <Icon icon="f7:arrowtriangle-right-fill" />
        {/snippet}
        {@const data = [
            {
                id: "beijing",
                title: "北京",
                children: [
                    { id: "gugong", title: "故宫" },
                    { id: "tiantan", title: "天坛" },
                ],
            },
            {
                id: "zhejiang",
                title: "浙江",
                children: [
                    { id: "xihu", title: "西湖" },
                    { id: "linyin", title: "灵隐" },
                ],
            },
        ]}
        <Tree {data} checkable directory {arrowIcon} />
    {/snippet}
</Story>

<Story name="Mod">
    {#snippet template(args)}
        {@const data = [
            {
                id: "beijing",
                title: "北京",
                children: [
                    { id: "gugong", title: "故宫" },
                    { id: "tiantan", title: "天坛" },
                ],
            },
            {
                id: "zhejiang",
                title: "浙江",
                children: [
                    { id: "xihu", title: "西湖" },
                    { id: "linyin", title: "灵隐" },
                ],
            },
        ]}
        {@const data2 = JSON.parse(JSON.stringify(data))}
        {@const data3 = JSON.parse(JSON.stringify(data))}
        {@const data4 = JSON.parse(JSON.stringify(data))}
        <Space dir="h" size={30}>
            <div>
                HALF:
                <Tree
                    {data}
                    checkable
                    directory
                    mode={TreeCheckMod.HALF}
                    onchange={(v) => {
                        console.log(v);
                    }}
                />
            </div>
            <div>
                FULL:
                <Tree
                    data={data2}
                    checkable
                    directory
                    mode={TreeCheckMod.FULL}
                    onchange={(v) => {
                        console.log(v);
                    }}
                />
            </div>
            <div>
                CHILD:
                <Tree
                    data={data3}
                    checkable
                    directory
                    mode={TreeCheckMod.CHILD}
                    onchange={(v) => {
                        console.log(v);
                    }}
                />
            </div>
            <div>
                SHALLOW:
                <Tree
                    data={data4}
                    checkable
                    directory
                    mode={TreeCheckMod.SHALLOW}
                    onchange={(v) => {
                        console.log(v);
                    }}
                />
            </div>
        </Space>
    {/snippet}
</Story>

<Story name="Search">
    {#snippet template(args)}
        {@const data = [
            {
                id: "beijing",
                title: "北京",
                children: [
                    { id: "gugong", title: "故宫" },
                    { id: "tiantan", title: "天坛" },
                ],
            },
            {
                id: "zhejiang",
                title: "浙江",
                children: [
                    { id: "xihu", title: "西湖" },
                    { id: "linyin", title: "灵隐" },
                ],
            },
        ]}
        <Input
            bind:value={searchKey}
            placeholder="Search"
            onchange={() => {
                searchTree.filter(searchKey);
            }}
        />
        <Tree {data} checkable directory bind:this={searchTree} />
    {/snippet}
</Story>

<Story name="Interfaces">
    {#snippet template(args)}
        {@const data = [
            {
                id: "beijing",
                title: "北京",
                children: [
                    { id: "gugong", title: "故宫" },
                    { id: "tiantan", title: "天坛" },
                ],
            },
            {
                id: "zhejiang",
                title: "浙江",
                children: [
                    { id: "xihu", title: "西湖" },
                    { id: "linyin", title: "灵隐" },
                ],
            },
        ]}
        <Tree {data} checkable directory bind:this={interfaceTree} />
        <Space dir="v">
            <Space dir="h">
                <Button
                    type="primary"
                    onclick={() => {
                        interfaceTree.checkNode("xihu", true);
                    }}>勾选</Button
                >

                <Button
                    type="primary"
                    onclick={() => {
                        interfaceTree.checkNode("xihu", false);
                    }}>取消勾选</Button
                >

                <Button
                    type="primary"
                    onclick={() => {
                        interfaceTree.checkAll();
                    }}>全选勾选</Button
                >

                <Button
                    type="primary"
                    onclick={() => {
                        interfaceTree.uncheckAll();
                    }}>取消全选</Button
                >
            </Space>
            <Space>
                <Button
                    type="primary"
                    onclick={() => {
                        console.log(interfaceTree.getChecked(TreeCheckMod.FULL));
                    }}>getChecked(FULL)</Button
                >
                <Button
                    type="primary"
                    onclick={() => {
                        console.log(interfaceTree.getChecked(TreeCheckMod.HALF));
                    }}>getChecked(HALF)</Button
                >
            </Space>
            <Space>
                <Button
                    type="primary"
                    onclick={() => {
                        console.log(interfaceTree.getChecked(TreeCheckMod.CHILD));
                    }}>getChecked(CHILD)</Button
                >
                <Button
                    type="primary"
                    onclick={() => {
                        console.log(interfaceTree.getChecked(TreeCheckMod.SHALLOW));
                    }}>getChecked(SHALLOW)</Button
                >
            </Space>
            <Space>
                <Button
                    type="primary"
                    onclick={() => {
                        console.log(interfaceTree.getCheckedKeys(TreeCheckMod.FULL));
                    }}>getCheckedKeys(FULL)</Button
                >
                <Button
                    type="primary"
                    onclick={() => {
                        console.log(interfaceTree.getCheckedKeys(TreeCheckMod.HALF));
                    }}>getCheckedKeys(HALF)</Button
                >
            </Space>
            <Space>
                <Button
                    type="primary"
                    onclick={() => {
                        console.log(interfaceTree.getCheckedKeys(TreeCheckMod.CHILD));
                    }}>getCheckedKeys(CHILD)</Button
                >
                <Button
                    type="primary"
                    onclick={() => {
                        console.log(interfaceTree.getCheckedKeys(TreeCheckMod.SHALLOW));
                    }}>getCheckedKeys(SHALLOW)</Button
                >
            </Space>
        </Space>
    {/snippet}
</Story>

<Story name="Apped">
    {#snippet template(args)}
        {@const data = [
            {
                id: "beijing",
                title: "北京",
                children: [
                    { id: "gugong", title: "故宫" },
                    { id: "tiantan", title: "天坛" },
                ],
            },
            {
                id: "zhejiang",
                title: "浙江",
                children: [
                    { id: "xihu", title: "西湖" },
                    { id: "linyin", title: "灵隐" },
                ],
            },
        ]}
        <Tree {data} checkable directory bind:this={appendTree} />
        <Space dir="v">
            <Space>
                <Button
                    type="primary"
                    onclick={() => {
                        appendTree?.append("beijing", {
                            id: `id_${Math.random()}`,
                            title: "appendNode",
                        });
                    }}>Append</Button
                >

                <Button
                    type="primary"
                    onclick={() => {
                        appendTree?.prepend("beijing", {
                            id: `id_${Math.random()}`,
                            title: "prependNode",
                        });
                    }}>Prepend</Button
                >
            </Space>

            <Space>
                <Button
                    type="primary"
                    onclick={() => {
                        appendTree?.insertBefore("gugong", {
                            id: `id_${Math.random()}`,
                            title: "insertBeforeNode",
                        });
                    }}>InsertBefore</Button
                >

                <Button
                    type="primary"
                    onclick={() => {
                        appendTree?.insertAfter("gugong", {
                            id: `id_${Math.random()}`,
                            title: "InsertAfterNode",
                        });
                    }}>InsertAfter</Button
                >
            </Space>
        </Space>
    {/snippet}
</Story>

<Story name="Rename">
    {#snippet template(args)}
        {@const data = [
            {
                id: "beijing",
                title: "北京",
                children: [
                    { id: "gugong", title: "故宫" },
                    { id: "tiantan", title: "天坛" },
                ],
            },
            {
                id: "zhejiang",
                title: "浙江",
                children: [
                    { id: "xihu", title: "西湖" },
                    { id: "linyin", title: "灵隐" },
                ],
            },
        ]}
        <Tree {data} checkable directory bind:this={renameTree} />
        <Button
            type="primary"
            onclick={() => {
                renameTree.rename("beijing", "renamed");
            }}>Rename</Button
        >
    {/snippet}
</Story>

<Story name="Vertual">
    {#snippet template(args)}
        {@const data = genData({ treeDepth: 3, nodesPerLevel: 10 }).data}
        <Tree {data} checkable directory virtual style={"max-height: 200px"} bind:this={bigTree} />
        <Space dir="v">
            <Space>
                <Button
                    type="primary"
                    onclick={() => {
                        bigTree.scrollTo(data[5].id);
                    }}>ScrollTo Top</Button
                >

                <Button
                    type="primary"
                    onclick={() => {
                        bigTree.scrollTo(data[5].id, "center");
                    }}>ScrollTo Center</Button
                >

                <Button
                    type="primary"
                    onclick={() => {
                        bigTree.scrollTo(data[5].id, "bottom");
                    }}>ScrollTo Bottom</Button
                >
            </Space>
        </Space>
    {/snippet}
</Story>
